<template>
  <view class="page">
    <div class="big-img" ref="bigImgContainer">
      <img
        class="image-big"
        :src="bigSrc"
        ref="imageElement"
        @load="imageLoaded"
        crossOrigin="anonymous"
        mode="widthFix "
      />
    </div>
    <view class="wearning-area">
      <view class="title">试戴角色</view>
      <view class="grid-box">
        <u-grid @click="gridClick" col="4">
          <u-grid-item v-for="(item, index) in peopleList" :key="index">
            <view :class="['grid-item', { gridActive: activeIndex === index }]">
              <image
                style="width: 100%; height: 100%"
                :src="item.small"
              ></image>
              <view v-if="activeIndex === index" class="check-box">
                <u-icon
                  class="check-icon"
                  name="checkbox-mark"
                  size="20rpx"
                  color="#fff"
                >
                </u-icon>
              </view>
            </view>
          </u-grid-item>
        </u-grid>
      </view>
    </view>
    <view class="wearning-area">
      <view class="title">您的照片</view>
      <view v-if="yourselfList.length" class="grid-box">
        <u-grid @click="yourGridClick" col="4">
          <u-grid-item v-for="(item, index) in yourselfList" :key="index">
            <view
              :class="['grid-item', { gridActive: yourActiveIndex === index }]"
            >
              <image
                style="width: 100%; height: 100%"
                :src="item"
                mode="aspectFill"
              ></image>
              <view v-if="yourActiveIndex === index" class="check-box">
                <u-icon
                  class="check-icon"
                  name="checkbox-mark"
                  size="20rpx"
                  color="#fff"
                >
                </u-icon>
              </view>
            </view>
          </u-grid-item>
        </u-grid>
      </view>
    </view>
    <u-upload @afterRead="afterRead">
      <view class="upload">上传您的照片</view>
    </u-upload>
    <view class="loading-box" v-if="loading">
      <u-loading-icon
        text="加载中"
        textSize="30"
        textColor="#fff"
        color="#fff"
        :show="loading"
      ></u-loading-icon>
    </view>
  </view>
</template>

<script>
import * as faceapi from "face-api.js";
export default {
  data() {
    return {
      bigSrc:
        "https://www.kapvoe.cn:8400/crmebimage/public/maintain/2025/03/08/f988307e28f3471a877453d3548f8cb393gg2cuqe3.jpg",
      activeIndex: 0,
      yourActiveIndex: 0,
      peopleList: [
        {
          big: "https://www.kapvoe.cn:8400/crmebimage/public/maintain/2025/03/08/f988307e28f3471a877453d3548f8cb393gg2cuqe3.jpg",
          small:
            "https://www.kapvoe.cn:8400/crmebimage/public/maintain/2025/03/08/f988307e28f3471a877453d3548f8cb393gg2cuqe3.jpg",
        },
        {
          big: "https://www.kapvoe.cn:8400/crmebimage/public/maintain/2025/03/08/d0c4e1d7789f4bedb9718da7f2a7b49faxv2civsuv.jpg",
          small:
            "https://www.kapvoe.cn:8400/crmebimage/public/maintain/2025/03/08/d0c4e1d7789f4bedb9718da7f2a7b49faxv2civsuv.jpg",
        },
      ],
      yourselfList: [],
      canvas: null,
      loading: false,
    };
  },
  methods: {
    gridClick(index) {
      if (this.activeIndex !== index) {
        this.removeCanvas();
        this.activeIndex = index;
        this.bigSrc = this.peopleList[index].big;
        this.yourActiveIndex = null;
      }
    },
    yourGridClick(index) {
      if (yourActiveIndex !== index) {
        this.removeCanvas();
        this.yourActiveIndex = index;
        this.bigSrc = this.yourselfList[index];
      }
    },
    afterRead(res) {
      this.removeCanvas();
      this.yourselfList.push(res.file.url);
      this.yourActiveIndex = this.yourselfList.length - 1;
      this.bigSrc = res.file.url;
      this.activeIndex = null;
    },
    imageLoaded(res) {
      this.loading = true;
      this.processImage();
    },
    async processImage() {
      // 确保图像元素已加载
      const imageElement = this.$refs.imageElement;
      if (!imageElement) return;

      // 加载模型
      try {
        await faceapi.nets.ssdMobilenetv1.loadFromUri("/static/models");
        await faceapi.nets.faceLandmark68Net.loadFromUri("/static/models");
      } catch (error) {
        console.error("Failed to load models:", error);
        return;
      }

      // 确保图像已加载完成
      this.detectFaces(imageElement);
    },

    detectFaces(imageElement) {
      faceapi
        .detectAllFaces(imageElement)
        .withFaceLandmarks()
        .then((detections) => {
          const displaySize = {
            width: imageElement.width,
            height: imageElement.height,
          };
          const canvas = document.createElement("canvas");
          canvas.width = imageElement.width;
          canvas.height = imageElement.height;
          canvas.style.position = "absolute";
          canvas.style.top = "0";
          canvas.style.left = "0";
          this.canvas = canvas;
          // 将 canvas 添加到 bigImgContainer 中
          this.$refs.bigImgContainer.appendChild(canvas);
          faceapi.matchDimensions(canvas, displaySize);

          const resizedDetections = faceapi.resizeResults(
            detections,
            displaySize
          );

          const ctx = canvas.getContext("2d");
          ctx.clearRect(0, 0, canvas.width, canvas.height);

          resizedDetections.forEach((detection) => {
            const leftEye = detection.landmarks.getLeftEye();
            const rightEye = detection.landmarks.getRightEye();
            const nose = detection.landmarks.getNose();
            const eyeDistance = faceapi.euclideanDistance(
              [leftEye[0].x, leftEye[0].y],
              [rightEye[3].x, rightEye[3].y]
            );
            console.log("eyeDistance", eyeDistance);

            // 设定眼镜宽度与眼睛距离的关系
            const glassesWidth = eyeDistance * 1.7; // 根据需要调整乘数
            const glassesHeight = glassesWidth / 2.75; // 眼镜高度设置为宽度的一半

            const midPoint = {
              x: (leftEye[0].x + rightEye[3].x) / 2,
              y: (leftEye[0].y + rightEye[3].y) / 2,
            };
            // 计算眼镜旋转角度
            const angle = Math.atan2(
              rightEye[0].y - leftEye[3].y,
              rightEye[0].x - leftEye[3].x
            );
            // 计算眼镜垂直位置的调整
            const noseTop = nose[0].y;
            const eyeLevel = (leftEye[0].y + rightEye[0].y) / 2;
            const verticalAdjustment = (noseTop - eyeLevel) * 0.6; // 调整系数可以根据需要修改
            const glassesImage = new Image();
            glassesImage.src = uni.getStorageSync("img");
            glassesImage.onload = () => {
              ctx.save(); // 保存当前的上下文状态
              ctx.translate(midPoint.x, midPoint.y + verticalAdjustment);
              ctx.rotate(angle);
              ctx.drawImage(
                glassesImage,
                -glassesWidth / 2,
                -glassesHeight / 2, // 根据高度进行调整
                glassesWidth,
                glassesHeight // 根据高度进行调整
              );
              ctx.restore(); // 恢复到之前保存的状态
              this.loading = false;
            };
          });
        })
        .catch((error) => {
          console.error("Error detecting faces:", error);
          this.loading = false;
        });
    },
    removeCanvas() {
      if (this.canvas) {
        this.$refs.bigImgContainer.removeChild(this.canvas);
        this.canvas = null; // 清空 canvas 引用
      }
    },
  },
};
</script>

<style lang="scss" scoped>
.page {
  width: 100%;
  height: 100vh;
  position: relative;
  .big-img {
    width: 100%;
    height: 716rpx;
    background: #d8d8d8;
    position: relative;
    // padding: 0 40rpx;
    box-sizing: border-box;
    .image-big {
      width: 100%;
      height: 100%;
    }
  }
  .wearning-area {
    .title {
      font-size: 32rpx;
      color: #1c1c1c;
      line-height: 42rpx;
      text-align: left;
      font-style: normal;
      margin: 40rpx 0 32rpx 36rpx;
    }
    .grid-box {
      .grid-item {
        width: 140rpx;
        height: 140rpx;
        position: relative;
        border-radius: 10rpx;
        border: 2px solid #e0e0e0;
        display: flex;
        align-items: center;
        justify-content: center;
        .check-box {
          position: absolute;
          top: 0;
          right: 0;
          width: 32rpx;
          height: 32rpx;
          background-color: #000;
          color: #fff;
          text-align: center;
          clip-path: polygon(0 0, 100% 0, 100% 100%);
        }
        .check-icon {
          position: absolute;
          top: 0;
          right: 0;
        }
        .more-color {
          font-size: 24rpx;
          color: #999;
          width: 80%;
          text-align: center;
        }
      }
      .gridActive {
        border: 2px solid #000;
      }
    }
  }
  .upload {
    width: 632rpx;
    height: 70rpx;
    background: #000000;
    border-radius: 44rpx;
    color: #ffffff;
    line-height: 70rpx;
    text-align: center;
    bottom: 20rpx;
    position: fixed;
    left: calc(50% - 316rpx);
    margin-bottom: calc(
      20rpx + constant(safe-area-inset-bottom)
    ); ///兼容 IOS<11.2/
    margin-bottom: calc(20rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
  }
  .loading-box {
    width: 100%;
    height: 100vh;
    position: absolute;
    top: 0;
    left: 0;
    background-color: rgba(0, 0, 0, 0.5);
    display: flex;
    align-items: center;
    justify-content: center;
  }
}
</style>
